package com.youshang.nio;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 *
 * @author youshang
 * @date 2021/01/21 18:28
 **/
public class MyService {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //设置当前服务端的通道为非阻塞
        serverSocketChannel.configureBlocking(false);
        InetSocketAddress inetSocketAddress = new InetSocketAddress("0.0.0.0",8888);
        serverSocketChannel.bind(inetSocketAddress);
        //注册到选择器上面,帮我们选择事件
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            //当前有多少客户端连接上
//            int select = selector.select();
            selector.select();
            //获取当前客户端集合
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
//                SelectionKey selectionKey = iterator.next();
//                if (selectionKey.isConnectable()){
//                    //获取serverSocketChannel
////                    SelectableChannel channel = selectionKey.channel();
//                    //获取对应客户端的channel
//                    SocketChannel socketChannel = serverSocketChannel.accept();
//                    //设置当前客户端的通道为非阻塞
//                    socketChannel.configureBlocking(false);
//                    //注册可读事件
//                    socketChannel.register(selector, SelectionKey.OP_READ);
//                }
//                if (selectionKey.isReadable()){
//                    handleRead((SocketChannel)selectionKey.channel());
//                }
                handleAccept(selector,iterator.next());
                //处理完之后移除当前客户端
                iterator.remove();
            }
        }
    }
    /**
     * 处理客户端写入的数据
     */
    private static void handleAccept(Selector selector,SelectionKey selectionKey) throws IOException {
        if (selectionKey.isAcceptable()){
            SocketChannel socketChannel = ((ServerSocketChannel) selectionKey.channel()).accept();
            socketChannel.configureBlocking(false);
            socketChannel.register(selector,SelectionKey.OP_READ);
//            System.out.println("123");
        }
        if (selectionKey.isReadable()) {
            handleRead((SocketChannel)selectionKey.channel());
        }
    }
    /**
     * 处理客户端写入的数据
     */
    private static void handleRead(SocketChannel socketChannel) throws IOException {
        //分配一个20个字节的缓冲区 ， 初始创建的byteBuffer的时候 limiter=capacity position = 0
        ByteBuffer byteBuffer = ByteBuffer.allocate(20);

        //Buffer 中最重要的几个属性
//        limit = position;
//        position = 0;
//        mark = -1;
        // position 会随着读取到Buffer的数据量变化而变化
        // channel写到buffer什么位置position就会显示什么(用于标记当前从channel读取到buffer的位置)
        socketChannel.read(byteBuffer);
        // buffer可操作的数据是position～limit之间的数据
        byteBuffer.flip();
        byte[] array = byteBuffer.array();
        String string = new String(array);
        System.out.println( string + "  "+ byteBuffer.slice());
        //如果当前Buffer中有数据
        while (byteBuffer.hasRemaining()) {
//            byte[] bytes = new byte[20];
            byte b = byteBuffer.get();
            System.out.println("读取客户端发送过来的消息   ReceiveBufferSize:" + socketChannel.socket().getReceiveBufferSize() + "    RemoteSocketAddress:" + socketChannel.socket().getRemoteSocketAddress()+
            "ReuseAddress: "+socketChannel.socket().getReuseAddress() + "   byte: "+ b);

        }

    }
}
